<template>
  <div style="margin: 20px">
    <!-- 分类级别选择卡片  -->
    <el-card>
      <CategorySelect
        @getCategoryId="getCategoryId"
        :showSelect="!showAttr"
      ></CategorySelect>
    </el-card>
    <!-- 展示详细信息卡片 -->
    <el-card style="margin-top: 20px" v-show="showAttr">
      <el-button
        type="primary"
        icon="el-icon-plus"
        @click="showAttr = false"
        :disabled="!category3Id"
        >添加属性</el-button
      >
      <el-table border style="width: 100%" :data="attrInfoList">
        <el-table-column type="index" label="序号" width="80">
        </el-table-column>
        <el-table-column prop="attrName" label="属性名称" width="150">
        </el-table-column>
        <el-table-column prop="prop" label="属性值列表">
          <!-- row => 就是每一个attr -->
          <template slot-scope="{ row }">
            <el-tag
              type="success"
              v-for="attrValue in row.attrValueList"
              :key="attrValue.id"
              style="margin-right: 10px"
              >{{ attrValue.valueName }}</el-tag
            >
          </template>
        </el-table-column>
        <el-table-column prop="prop" label="操作" width="150">
          <template slot-scope="{ row }">
            <el-button
              type="warning"
              icon="el-icon-edit"
              size="mini"
              style="margin-right: 10px"
              @click="updateAttr(row)"
            ></el-button>
            <el-popconfirm
              :title="`确定要删除${row.attrName}?`"
              @onConfirm="deleteAttr(row.id)"
            >
              <el-button
                type="danger"
                icon="el-icon-delete"
                size="mini"
                slot="reference"
              ></el-button>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 添加|修改属性卡片 -->
    <el-card v-show="!showAttr" style="margin-top: 20px">
      <el-form class="demo-form-inline" label-width="80px" :model="attrList">
        <el-form-item label="属性名">
          <el-input
            placeholder="请输入属性名"
            style="width: 180px"
            v-model="attrList.attrName"
          ></el-input>
        </el-form-item>
      </el-form>
      <el-button
        type="primary"
        icon="el-icon-plus"
        :disabled="!attrList.attrName"
        @click="addAttrValue"
        >添加属性值</el-button
      >
      <el-button @click="cancelAddOrEdit">取消</el-button>
      <el-table
        :data="attrList.attrValueList"
        border
        style="width: 100%; margin: 20px 0"
      >
        <el-table-column type="index" label="序号" width="80" align="center">
        </el-table-column>
        <el-table-column prop="valueName" label="属性值名称">
          <template slot-scope="{ row, $index }">
            <el-input
              placeholder="请输入属性值名称"
              v-model="row.valueName"
              size="mini"
              v-if="row.isShowInput"
              @blur="updateIsShowInput(row, $index)"
              @keyup.enter.native="updateIsShowInput(row, $index)"
              :ref="$index"
            ></el-input>
            <span
              v-else
              @click="changeIsShowInput(row, $index)"
              style="display: block"
              >{{ row.valueName }}</span
            >
          </template>
        </el-table-column>
        <el-table-column prop="prop" label="操作">
          <template slot-scope="{ row, $index }">
            <el-popconfirm
              :title="`确定删除${row.valueName}?`"
              @onConfirm="confirmDelete($index)"
            >
              <el-button
                type="danger"
                icon="el-icon-delete"
                size="mini"
                slot="reference"
              ></el-button>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-button
        type="primary"
        :disabled="attrList.attrValueList.length < 1"
        @click="addAttr"
        >保存</el-button
      >
      <el-button @click="cancelAddOrEdit">取消</el-button>
    </el-card>
  </div>
</template>

<script>
// 引入lodash库中的深克隆函数
import cloneDeep from "lodash/cloneDeep";
export default {
  name: "Attr",
  data() {
    return {
      // 一级分类id
      category1Id: "",
      // 二级分类id
      category2Id: "",
      // 三级分类id
      category3Id: "",
      // 平台属性列表
      attrInfoList: [],
      // 是否展示平台属性(也就是是否进行添加跟修改)
      showAttr: true,
      // 添加|修改要携带的数据
      attrList: {
        id: "",
        attrName: "",
        attrValueList: [],
        categoryId: 0,
        categoryLevel: 3,
      },
    };
  },
  methods: {
    // 自定义事件，获取从子组件传过来的分类id，并且当三级分类id得到后，发送请求，获取属性值进行展示
    getCategoryId(categoryIdList) {
      const { category1Id, category2Id, category3Id } = categoryIdList;
      this.category1Id = category1Id;
      this.category2Id = category2Id;
      this.category3Id = category3Id;
      // 只有当三级分类id有了后，才发送获取平台属性数据接口的函数
      if (categoryIdList.category3Id) {
        this.getAttrInfoList();
      } else {
        // 三级分类id还没有，平台属性数据为空数组
        this.attrInfoList = [];
      }
    },
    // 获取平台属性数据
    async getAttrInfoList() {
      const result = await this.$API.attr.reqAttrInfoList(
        this.category1Id,
        this.category2Id,
        this.category3Id
      );
      if (result.code === 200) {
        this.attrInfoList = result.data;
      }
    },
    // 添加属性值
    addAttrValue() {
      this.attrList.attrValueList.push({
        valueName: "",
        isShowInput: true,
      });
      // 一开始也让文本框获得焦点
      this.$nextTick(() => {
        // 点击添加属性的时候，总是让最后一个文本框获得焦点
        this.$refs[this.attrList.attrValueList.length - 1].focus();
      });
    },
    // 显示文本框
    changeIsShowInput(row, index) {
      row.isShowInput = true;
      // 不使用nextTickd的话，刚开始找不到要聚焦的文本框
      this.$nextTick(() => {
        this.$refs[index].focus();
      });
    },
    // 隐藏文本框
    updateIsShowInput(row, index) {
      // 判断输入的属性值是否正常
      if (row.valueName.trim() === "") {
        this.$message({
          message: "请你输入一个正常的属性值",
          center: true,
        });
        return;
      }
      // 创建一个临时数组(深拷贝，不会改变原数组)
      const tempArr = JSON.parse(JSON.stringify(this.attrList.attrValueList));
      // 去除掉数组中本次要验证的属性值
      tempArr.splice(index, 1);
      // 判断当前输入的属性值是否已经存在
      if (
        this.attrList.attrValueList.length > 1 &&
        tempArr.some((item) => item.valueName.trim() === row.valueName.trim())
      ) {
        this.$message({
          message: "该属性值已经拥有了，请重新输入",
          center: true,
        });
        return;
      }
      row.isShowInput = false;
    },
    // 当点击气泡提示框的确认按钮后，删除当前行的数据
    confirmDelete(index) {
      this.attrList.attrValueList.splice(index, 1);
    },
    // 点击取消按钮时，回到展示平台属性的页面
    cancelAddOrEdit() {
      this.showAttr = true;
      // 将数据清空
      this.attrList.attrName = "";
      this.attrList.attrValueList = [];
    },
    // 点击保存按钮，发送请求，新增属性
    async addAttr() {
      // 整合要发送到服务端的数据
      if (!this.attrList.id) {
        delete this.attrList.id;
      }
      // 去掉数组中每一项的isShowInput属性，因为其不发送给服务器
      const tempArr = this.attrList.attrValueList.map((item) => {
        delete item.isShowInput;
        return item;
      });
      // 去掉属性值中的空项, 并将其整合到attrList中
      this.attrList.attrValueList = tempArr.filter((item) => item.valueName);
      this.attrList.categoryId = this.category3Id;
      const result = await this.$API.attr.reqSaveAttrInfo(this.attrList);
      // 重新展示属性表格
      this.showAttr = true;
      if (result.code === 200) {
        this.$message({
          message: "保存成功",
          type: "success",
        });
        // 重新获取平台属性进行展示
        this.getAttrInfoList();
      } else {
        this.$message({
          message: "保存失败",
          type: "error",
        });
      }
    },
    // 修改属性的业务(跟增加业务完全一样)
    updateAttr(row) {
      this.showAttr = false;
      // 将要修改的属性深克隆到attrList
      this.attrList = cloneDeep(row);
      // 需要自己手动添加判断是否显示文本框的属性
      // 而且必须是响应式的
      this.attrList.attrValueList.forEach((item) => {
        this.$set(item, "isShowInput", false);
      });
    },
    // 点击确定，删除当前的属性
    async deleteAttr(id) {
      try {
        await this.$API.attr.reqDeleteAttr(id);
        // 删除成功，弹出成功的提示
        this.$message({
          message: "删除成功",
          type: "success",
        });
        // 删除成功，重新获取平台属性进行展示
        this.getAttrInfoList();
      } catch (error) {
        this.$message({
          message: "删除失败",
          type: "error",
        });
      }
    },
  },
};
</script>

<style>
</style>